package com.earnings.okhttputils.utils.OkHttp.request;

import android.content.Context;

import com.earnings.okhttputils.utils.OkHttp.OkHttpUtils;
import com.earnings.okhttputils.utils.OkHttp.callback.Callback;
import com.earnings.okhttputils.utils.OkHttp.utils.Md5Utils;
import com.earnings.okhttputils.utils.OkHttp.utils.PhoneFormatCheckUtils;
import com.earnings.okhttputils.utils.OkHttp.utils.Versions;
import com.earnings.okhttputils.utils.User;
import com.earnings.okhttputils.utils.utils.CommonUtil;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;


/**
 * Created by zhy on 15/12/15.
 * 对OkHttpRequest的封装，对外提供更多的接口：cancel(),readTimeOut()...
 */
public class RequestCall {
    private OkHttpRequest okHttpRequest;
    private Request request;
    private Call call;
    private Context mContext;
    private long readTimeOut;
    private long writeTimeOut;
    private long connTimeOut;
    private CacheMode cacheMode;
    private OkHttpClient clone;

    public RequestCall(OkHttpRequest request) {

        this.okHttpRequest = request;
    }

    public String getUrl() {
        return okHttpRequest.getUrl();
    }

    public Context getContext() {
        if (mContext != null) {
            return mContext;
        }
        return null;
    }

    public Map<String, String> getParams() {
        return okHttpRequest.getParams();
    }

    public void setParams(Map<String, String> map) {
        okHttpRequest.setParams(map);
    }

    public CacheMode getCacheMode() {
        return cacheMode;
    }

    public RequestCall readTimeOut(long readTimeOut) {
        this.readTimeOut = readTimeOut;
        return this;
    }

    public RequestCall writeTimeOut(long writeTimeOut) {
        this.writeTimeOut = writeTimeOut;
        return this;
    }

    public RequestCall connTimeOut(long connTimeOut) {
        this.connTimeOut = connTimeOut;
        return this;
    }

    public Call buildCall(Callback callback) {
        request = generateRequest(callback);

        if (readTimeOut > 0 || writeTimeOut > 0 || connTimeOut > 0) {
            readTimeOut = readTimeOut > 0 ? readTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS;
            writeTimeOut = writeTimeOut > 0 ? writeTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS;
            connTimeOut = connTimeOut > 0 ? connTimeOut : OkHttpUtils.DEFAULT_MILLISECONDS;

            clone = OkHttpUtils.getInstance().getOkHttpClient().newBuilder()
                    .readTimeout(readTimeOut, TimeUnit.MILLISECONDS)
                    .writeTimeout(writeTimeOut, TimeUnit.MILLISECONDS)
                    .connectTimeout(connTimeOut, TimeUnit.MILLISECONDS)
                    .build();

            call = clone.newCall(request);
        } else {
            call = OkHttpUtils.getInstance().getOkHttpClient().newCall(request);
        }
        return call;
    }


    private Request generateRequest(Callback callback) {
        return okHttpRequest.generateRequest(callback);
    }

    public void execute(Callback callback) {
        buildCall(callback);
        if (callback != null) {
            callback.onBefore(request, getOkHttpRequest().getId());
        }

        OkHttpUtils.getInstance().execute(this, callback);
    }

    public void execute(Context context, Callback callback, CacheMode cacheMode) {
        mContext = context;
        this.cacheMode = cacheMode;
        if (mContext != null) {

            if (okHttpRequest.getParams() == null) {
                okHttpRequest.setParams(new LinkedHashMap<String, String>());
            }
            User user= CommonUtil.getUser();
            String UniqueID = PhoneFormatCheckUtils.getPesudoUniqueID();
            String currentTime = new Date().getTime() + "";
            String userName = user.getNickname();
            String password =user.getPassword();
            String str = Md5Utils.getMd5User(password, UniqueID, userName, currentTime);
            String token = user.getToken();
            String user_id = user.getUser_id();
            okHttpRequest.getParams().put("token", token);
            okHttpRequest.getParams().put("unique_id", UniqueID);
            okHttpRequest.getParams().put("user_id",user_id);
            okHttpRequest.getParams().put("sing", str);
            okHttpRequest.getParams().put("time", currentTime);
            okHttpRequest.getParams().put("version", Versions.getVersionName(context));
            okHttpRequest.getParams().put("client", "android");
            okHttpRequest.getParams().put("app_type", 2+"");
            if (okHttpRequest instanceof GetRequest) {
                okHttpRequest.setUrl(okHttpRequest.getUrl() + "&token=" + token + "&unique_id=" + UniqueID + "&sing=" + str + "&time=" + currentTime + "&user_id=" + user_id+"&app_type=" + 2);
                okHttpRequest.initBuilder();
            }
        }
        //生成一个okhttp的回调 如果是post则在这里进行参数拼接形成body
        buildCall(callback);
        if (callback != null) {
            callback.onBefore(request, getOkHttpRequest().getId());
        }
        OkHttpUtils.getInstance().execute(this, callback);
    }

    public void execute(Context context, Callback callback) {
        execute(context, callback, CacheMode.ONLY_NETWORK);
    }

    public Call getCall() {
        return call;
    }

    public Request getRequest() {
        return request;
    }

    public OkHttpRequest getOkHttpRequest() {
        return okHttpRequest;
    }


    public void cancel() {
        if (call != null) {
            call.cancel();
        }
    }

    /**
     * ONLY_CACHE 每次访问接口 都是读取缓存
     * CACHE_AND_NETWORK 每次访问接口 先读取缓存，接着访问网络
     * ONLY_NETWORK 每次访问接口 都是由网络读取
     * CYCLE_NETWORK 每次访问接口 在时间周期中都是读取缓存，过了时间周期由网络读取一次最新数据
     *
     * @author jie.yang
     */
    public enum CacheMode {
        ONLY_CACHE,
        CACHE_AND_NETWORK,
        ONLY_NETWORK,
        CYCLE_NETWORK
    }
}
